package craky.componentc;

import java.awt.Color;
import java.awt.Container;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsEnvironment;
import java.awt.HeadlessException;
import java.awt.Image;
import java.awt.Insets;
import java.awt.Rectangle;
import java.awt.Window;
import java.awt.image.BufferedImage;

import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JRootPane;

import com.abigdreamer.swing.component.UIUtil;
import com.sun.awt.AWTUtilities;

import craky.component.JImagePane;
import craky.util.Util;

public class JCFrame extends JFrame {
	
	private static final long serialVersionUID = 854652168416021730L;
	private boolean titleOpaque;
	private boolean borderPainted;
	private boolean isMaximizedBoundsSet;
	private Image backgroundImage;
	private CRootPaneUI.ImageDisplayMode imageDisplayMode;
	private float imageAlpha;
	private CRootPaneUI ui;

	public JCFrame() throws HeadlessException {
		init();
	}

	public JCFrame(GraphicsConfiguration gc) {
		super(gc);
		init();
	}

	public JCFrame(String title) throws HeadlessException {
		super(title);
		init();
	}

	public JCFrame(String title, GraphicsConfiguration gc) {
		super(title, gc);
		init();
	}

	private void init() {
		this.borderPainted = true;
		this.imageDisplayMode = CRootPaneUI.ImageDisplayMode.TILED;
		this.imageAlpha = 1.0F;
		JRootPane root = getRootPane();
		Container contentPane = getContentPane();
		setFont(UIUtil.getDefaultFont());
		setUndecorated(true);
		root.setUI(this.ui = new CRootPaneUI());
		root.setForeground(Color.BLACK);
		root.setBackground(new Color(233, 242, 249));
		root.setWindowDecorationStyle(1);
		setBackground(root.getBackground());

		if ((contentPane instanceof JComponent)) {
			((JComponent) contentPane).setOpaque(false);
		}
	}

	protected JRootPane createRootPane() {
		JRootPane rp = new JRootPane() {
			private static final long serialVersionUID = 6817397706458749155L;

			@Deprecated
			public void updateUI() {
			}
		};
		rp.setOpaque(true);
		return rp;
	}

	public synchronized void setMaximizedBounds(Rectangle bounds) {
		this.isMaximizedBoundsSet = (bounds != null);
		super.setMaximizedBounds(bounds);
	}

	public synchronized void setExtendedState(int state) {
		if ((Util.isWindows()) && ((state & 0x6) != 0) && (!this.isMaximizedBoundsSet)) {
			Rectangle bounds = getGraphicsConfiguration().getBounds();
			Rectangle maxBounds = null;

			if ((bounds.x == 0) && (bounds.y == 0)) {
				Insets screenInsets = getToolkit().getScreenInsets(getGraphicsConfiguration());
				maxBounds = new Rectangle(screenInsets.left, screenInsets.top, bounds.width - screenInsets.right - screenInsets.left, bounds.height - screenInsets.bottom - screenInsets.top);
			}

			super.setMaximizedBounds(maxBounds);
		}

		super.setExtendedState(state);
	}

	public synchronized int getExtendedState() {
		int state = super.getExtendedState();

		if (Util.isWindows()) {
			Window fullWin = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getFullScreenWindow();
			return this == fullWin ? state | 0x6 : state;
		}

		return state;
	}

	public boolean isTitleOpaque() {
		return this.titleOpaque;
	}

	public void setTitleOpaque(boolean titleOpaque) {
		if (this.titleOpaque != titleOpaque) {
			this.titleOpaque = titleOpaque;
			getRootPane().repaint();
		}
	}

	public BufferedImage getEdgeBlurImage() {
		return this.ui.getEdgeBlurImage();
	}

	public Image getBackgroundImage() {
		return this.backgroundImage;
	}

	public void setBackgroundImage(Image backgroundImage) {
		setBackgroundImage(backgroundImage, null);
	}

	public void setBackgroundImage(Image backgroundImage, BufferedImage edgeBlurImage) {
		if (this.backgroundImage != backgroundImage) {
			this.backgroundImage = backgroundImage;
			this.ui.removeBlurImage();
			this.ui.setEdgeBlurImage(edgeBlurImage);
			getRootPane().repaint();
		}
	}

	public boolean isBorderPainted() {
		return this.borderPainted;
	}

	public void setBorderPainted(boolean borderPainted) {
		if (this.borderPainted != borderPainted) {
			this.borderPainted = borderPainted;
			getRootPane().repaint();
		}
	}

	public CRootPaneUI.ImageDisplayMode getImageDisplayMode() {
		return this.imageDisplayMode;
	}

	public void setImageDisplayMode(CRootPaneUI.ImageDisplayMode imageDisplayMode) {
		if (this.imageDisplayMode != imageDisplayMode) {
			this.imageDisplayMode = imageDisplayMode;
			getRootPane().repaint();
		}
	}

	public float getImageAlpha() {
		return this.imageAlpha;
	}

	public void setImageAlpha(float imageAlpha) {
		if ((imageAlpha >= 0.0F) && (imageAlpha <= 1.0F)) {
			this.imageAlpha = imageAlpha;
			repaint();
		} else {
			throw new IllegalArgumentException("Invalid alpha:" + imageAlpha);
		}
	}

	public JImagePane getTitleContentPane() {
		return this.ui.getTitleContentPane();
	}

	public void copyBackgroundImage(Container c) {
		setBackgroundImage(UIUtil.getBackgroundImageFromContainer(c), UIUtil.getEdgeBlurImageFromContainer(c));
		setImageDisplayMode(UIUtil.getImageDisplayModeFromContainer(c));
		setImageAlpha(UIUtil.getImageAlphaFromContainer(c));
		repaint();

		Window parent = UIUtil.getWindowFromComponent(c);
		float alpha = 1.0F;

		if ((parent != null) && (UIUtil.isTranslucencySupported()) && ((alpha = AWTUtilities.getWindowOpacity(parent)) < 1.0F)) {
			AWTUtilities.setWindowOpacity(this, alpha);
		}
	}
}